package aggregate.test.remoteclient;

import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
import java.util.List;
import java.util.Random;

import aggregate.aggregator.remote.AggregatorRemoteInterface;
import aggregate.aggregator.remote.Category;
import aggregate.aggregator.remote.ClientRemoteInterface;
import aggregate.aggregator.remote.Comment;
import aggregate.aggregator.remote.ContentItem;

public class RemoteClient implements ClientRemoteInterface {
		
	private AggregatorRemoteInterface aggregator;
	Random rand;

	public RemoteClient(AggregatorRemoteInterface aggregator) {
		this.aggregator = aggregator;
		this.rand = new Random();
	}

	/**
	 * The first argument represents the hostname by which the Aggregator service
	 * can be located.
	 * 
	 * The second argument represents the hostname by which the Client application
	 * can be located (by the Aggregator server).
	 * 
	 * For example, if the Aggregator runs on a server with the IP 192.168.186.130
	 * and this application is run from the IP 192.168.186.128, the command to start
	 * the client is this:
	 * 
	 * 	java -jar remoteclient.jar 192.168.186.130 192.168.186.128
	 * 
	 * If they are missing, localhost is taken as default.
	 */
	public static void main(String args[]) {
		String aggregatorHostname = "localhost";
		String clientHostname = "localhost";
		
		if (args.length > 0) {
			aggregatorHostname = args[0];
		}
		if (args.length > 1) {
			clientHostname = args[1];
		}
		
		try {			
		    AggregatorRemoteInterface aggregator = getAggregator(aggregatorHostname);
		    ClientRemoteInterface client = exportRemoteClient(aggregator);
		    
//		    List<Category> categories = aggregator.getCategories();
//		    listCategories(categories);
//		    Category category = selectCategory(categories);
//		    System.out.println("Selected category: " + category.getName());
//		    
		    aggregator.subscribe(clientHostname, 2);
		} catch (Exception e) {
		    e.printStackTrace();
		}
	}

	private static ClientRemoteInterface exportRemoteClient(AggregatorRemoteInterface aggregator) throws RemoteException {
		ClientRemoteInterface client = new RemoteClient(aggregator);
		ClientRemoteInterface clientStub = (ClientRemoteInterface)
				UnicastRemoteObject.exportObject(client, 0);
		
		Registry registry = LocateRegistry.createRegistry(5002);
		registry.rebind("ClientApplication", clientStub);
		return client;
	}

	private static AggregatorRemoteInterface getAggregator(String host)
			throws RemoteException, NotBoundException, AccessException {
		Registry registry = LocateRegistry.getRegistry(host, 5001);
		AggregatorRemoteInterface aggregator = (AggregatorRemoteInterface)
			registry.lookup("Aggregator");
		return aggregator;
	}

	private static Category selectCategory(List<Category> categories) {
		Random rand = new Random();
		return categories.get(rand.nextInt(categories.size()));
	}

	private static void listCategories(List<Category> categories) {
		System.out.println("{ ");
		for (Category category : categories) {
			System.out.println("  " + category.getId() + " " + category.getName());
		}
		System.out.println("}");
	}

	@Override
	public void notify(ContentItem item) throws RemoteException {
		double rating = rand.nextDouble() * 4.0 + 1.0;
		System.out.println("Received: " + item.getTitle() + " - " + rating);
		aggregator.addRating(item.getId(), rating);
		if (rating > 4.0) {
			aggregator.addComment(item.getId(), new Comment("Ce rating mare! " + new Date(), "rating", "ion"));
		}
	}

	@Override
	public void notifyRating(int contentId, double value)
			throws RemoteException {
		System.out.println(contentId + " - " + value);
	}

	@Override
	public void notifyComment(Comment comment) {
		System.out.println("Comment: " + comment.getBody());
	}
}
